package com.lerays.spider.sougou;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Properties;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import com.lerays.spider.sougou.handler.ControlRequestHandler;
import com.lerays.spider.sougou.handler.SessionAddRequestHandler;
import com.lerays.spider.sougou.handler.SessionClearRequestHandler;
import com.lerays.spider.sougou.handler.SessionListRequestHandler;
import com.lerays.spider.sougou.handler.SettingRequestHandler;
import com.lerays.spider.sougou.handler.StatusRequestHandler;
import com.lerays.spider.sougou.utils.Utils;
import com.sun.net.httpserver.HttpServer;

/**
 * spider http server. <br />
 * 
 * @author chenxin<chenxin619315@gmail.com>
 */
public class SpiderHttpServer 
{	
	//default server port
	public static int DEFAULT_PORT = 4306;
	
	//server resources 
	private int port = 0;
	private HttpServer httpServer = null;
	
	//wechat spider
	private SougouSpider sougouSpider = null;
	
	public SpiderHttpServer()
	{
		this(DEFAULT_PORT);
	}
	
	public SpiderHttpServer( int port )
	{
		this.port = port;
	}
	
	/**
	 * initialize the server <br />
	 * 1. load the spider.conf
	 * 2. create the server socket
	 * 3. prepare the thread pool 
	 * 
	 * @throws IOException
	 */
	public SpiderHttpServer init() throws IOException
	{
		//load the spider.conf
		Properties pro = Utils.loadConf("spider.conf");
		if ( pro.containsKey("server.port") ) 
		{
			port = Integer.valueOf(pro.getProperty("server.port"));
		}
		
		httpServer = HttpServer.create(new InetSocketAddress(port), 0);
		httpServer.createContext("/_setting", 	new SettingRequestHandler(this));
		httpServer.createContext("/_status", 	new StatusRequestHandler(this));
		httpServer.createContext("/_control", 	new ControlRequestHandler(this));
		httpServer.createContext("/session/add",  new SessionAddRequestHandler(this));
		httpServer.createContext("/session/list", new SessionListRequestHandler(this));
		httpServer.createContext("/session/clear", new SessionClearRequestHandler(this));
				
		//create a thread pool executor
		ThreadPoolExecutor threadPool = new ThreadPoolExecutor( 
				5, 15, 5, 
				TimeUnit.SECONDS, 
				new ArrayBlockingQueue<Runnable>(50), 
        		new ThreadPoolExecutor.DiscardOldestPolicy()
		);
		httpServer.setExecutor(threadPool);
		
		//create a spider
		sougouSpider = new SougouSpider();
		return this;
	}
	
	public SougouSpider getsougouSpider() 
	{
		return sougouSpider;
	}
	
	public int getPort()
	{
		return port;
	}

	/**
	 * start the server. <br />
	 * 1. initialize the spider
	 * 2. start the client accept thread
	 */
	public void start()
	{
		//start the main spider
		sougouSpider.start();
		
		//start the http server
		httpServer.start();
	}
	
	/**
	 * shutdown the server. <br />
	 * 1. stop the http server
	 * 2. shutdown the spider
	 */
	public void shutdown()
	{
		httpServer.stop(0);
		sougouSpider.shutdown();
	}

	public static void main(String[] args) 
	{
		SpiderHttpServer server = new SpiderHttpServer();
		
		try {
			server.init().start();
			System.out.println("[Info]: spider server started on port: " + server.getPort());
		} catch (IOException e) {
			System.out.println("[Error]: Unable to start the server for " + e);
		}
	}

}
